// 日志工具类
class Logger {
    constructor(prefix = '') {
        this.prefix = prefix;
        this.debugMode = true;  // 可以通过这个开关控制是否输出日志
    }

    // 设置前缀
    setPrefix(prefix) {
        this.prefix = prefix;
    }

    // 启用/禁用调试模式
    setDebugMode(enabled) {
        this.debugMode = enabled;
    }

    // 格式化前缀
    formatPrefix(category = '') {
        return `[${this.prefix}${category ? ':' + category : ''}]`;
    }

    // 基础日志方法
    log(message, category = '') {
        if (!this.debugMode) return;
        console.log(`${this.formatPrefix(category)}`, message);
    }

    // 打印对象的详细信息
    dir(obj, category = '') {
        if (!this.debugMode) return;
        console.log(`${this.formatPrefix(category)} 对象详细信息:`);
        console.dir(obj);
    }




 getAllMethods(obj) {
  const methods = new Set();

  while (obj) {
    Object.getOwnPropertyNames(obj).forEach(prop => {
      if (typeof obj[prop] === 'function') {
        methods.add(prop);
      }
    });
    obj = Object.getPrototypeOf(obj);
  }

  return [...methods];
}


 getOwnMethods(obj) {
  return Object.getOwnPropertyNames(obj).filter(
    prop => typeof obj[prop] === 'function'
  );
}


 getOwnMethodsIncludingSymbols(obj) {
  return Reflect.ownKeys(obj).filter(
    key => typeof obj[key] === 'function'
  );
}


    // 获取对象的所有方法
    getAllMethods(obj) {
        if (!obj) return [];
        
        let methods = new Set();
        let current = obj;
        
        // 获取所有可能的方法名
        const getMethods = (object) => {
            // 获取自身和原型链上的所有属性
            const properties = new Set([
                ...Object.getOwnPropertyNames(object),
                ...Object.keys(object),
                ...(object.prototype ? Object.getOwnPropertyNames(object.prototype) : [])
            ]);

            properties.forEach(prop => {
                try {
                    const descriptor = Object.getOwnPropertyDescriptor(object, prop);
                    // 检查是否是方法
                    if (descriptor && typeof descriptor.value === 'function') {
                        methods.add(prop);
                    }
                    // 检查 getter/setter
                    if (descriptor && (descriptor.get || descriptor.set)) {
                        if (descriptor.get) methods.add(`get ${prop}`);
                        if (descriptor.set) methods.add(`set ${prop}`);
                    }
                } catch (e) {
                    // 忽略访问错误
                }
            });
        };

        try {
            // 遍历原型链
            while (current) {
                getMethods(current);
                try {
                    current = Object.getPrototypeOf(current);
                } catch (e) {
                    break;
                }
                // 如果到达了 Object.prototype 或 null，停止遍历
                if (current === Object.prototype || current === null) {
                    getMethods(Object.prototype);
                    break;
                }
            }
        } catch (e) {
            console.warn("遍历原型链时出错:", e);
        }

        return Array.from(methods);
    }

    // 打印对象的所有方法
    printMethods(obj, objName = "对象", category = '', showImplementation = false) {
        if (!this.debugMode || !obj) return;
        
        const prefix = this.formatPrefix(category);
        console.group(`${prefix} ${objName}的所有方法:`);
        
        try {
            const methods = this.getAllMethods(obj);
            methods.sort();

            // 分类显示方法
            const categorizedMethods = {
                getters: methods.filter(m => m.startsWith('get ')),
                setters: methods.filter(m => m.startsWith('set ')),
                regular: methods.filter(m => !m.startsWith('get ') && !m.startsWith('set '))
            };

            // 显示常规方法
            if (categorizedMethods.regular.length > 0) {
                console.group('常规方法:');
                categorizedMethods.regular.forEach(methodName => {
                    try {
                        const method = obj[methodName];
                        const methodStr = method.toString();
                        if (showImplementation) {
                            console.log(`${methodName}:`, methodStr);
                        } else {
                            // 保留函数定义，去掉函数体
                            const funcDefMatch = methodStr.match(/^(function\s*[\w$]*\s*\([^)]*\))/);
                            if (funcDefMatch) {
                                // 标准函数定义
                                console.log(`${methodName}:`, `${funcDefMatch[1]} { ... }`);
                            } else {
                                // 箭头函数或其他格式的函数
                                const arrowFuncMatch = methodStr.match(/^(\([^)]*\)|[\w$]+)\s*=>/);
                                if (arrowFuncMatch) {
                                    console.log(`${methodName}:`, `${arrowFuncMatch[1]} => { ... }`);
                                } else {
                                    // 尝试提取参数列表
                                    const paramMatch = methodStr.match(/\(([^)]*)\)/);
                                    if (paramMatch) {
                                        console.log(`${methodName}:`, `function(${paramMatch[1]}) { ... }`);
                                    } else {
                                        // 如果无法提取参数，至少显示为函数
                                        console.log(`${methodName}:`, `function() { ... }`);
                                    }
                                }
                            }
                        }
                    } catch (e) {
                        // 如果无法获取函数定义，至少显示为函数
                        console.log(`${methodName}:`, `function() { ... }`);
                    }
                });
                console.groupEnd();
            }

            // 显示 getters
            if (categorizedMethods.getters.length > 0) {
                console.group('Getters:');
                categorizedMethods.getters.forEach(getter => {
                    try {
                        const descriptor = Object.getOwnPropertyDescriptor(obj, getter.slice(4));
                        if (descriptor && descriptor.get) {
                            const getterStr = descriptor.get.toString();
                            if (showImplementation) {
                                console.log(`${getter}:`, getterStr);
                            } else {
                                const funcDefMatch = getterStr.match(/^(function\s*[\w$]*\s*\([^)]*\))/);
                                if (funcDefMatch) {
                                    console.log(`${getter}:`, `${funcDefMatch[1]} { ... }`);
                                } else {
                                    console.log(`${getter}:`, `get ${getter.slice(4)}() { ... }`);
                                }
                            }
                        } else {
                            console.log(`${getter}:`, `get ${getter.slice(4)}() { ... }`);
                        }
                    } catch (e) {
                        console.log(`${getter}:`, `get ${getter.slice(4)}() { ... }`);
                    }
                });
                console.groupEnd();
            }

            // 显示 setters
            if (categorizedMethods.setters.length > 0) {
                console.group('Setters:');
                categorizedMethods.setters.forEach(setter => {
                    try {
                        const descriptor = Object.getOwnPropertyDescriptor(obj, setter.slice(4));
                        if (descriptor && descriptor.set) {
                            const setterStr = descriptor.set.toString();
                            if (showImplementation) {
                                console.log(`${setter}:`, setterStr);
                            } else {
                                const funcDefMatch = setterStr.match(/^(function\s*[\w$]*\s*\([^)]*\))/);
                                if (funcDefMatch) {
                                    console.log(`${setter}:`, `${funcDefMatch[1]} { ... }`);
                                } else {
                                    console.log(`${setter}:`, `set ${setter.slice(4)}(value) { ... }`);
                                }
                            }
                        } else {
                            console.log(`${setter}:`, `set ${setter.slice(4)}(value) { ... }`);
                        }
                    } catch (e) {
                        console.log(`${setter}:`, `set ${setter.slice(4)}(value) { ... }`);
                    }
                });
                console.groupEnd();
            }
        } catch (e) {
            console.warn(`${prefix} 打印方法时出错:`, e);
        }
        console.groupEnd();
    }

    // 打印对象的所有属性
    printProperties(obj, objName = "对象", category = '') {
        if (!this.debugMode || !obj) return;
        
        const prefix = this.formatPrefix(category);
        console.group(`${prefix} ${objName}的所有属性:`);
        
        try {
            // 使用 console.dir 打印完整的对象结构
            console.dir(obj);
            
            // 获取对象的原型链
            let proto = Object.getPrototypeOf(obj);
            if (proto && proto !== Object.prototype) {
                console.group('原型链:');
                while (proto && proto !== Object.prototype) {
                    console.log(`- ${proto.constructor ? proto.constructor.name : 'Unknown'}`);
                    proto = Object.getPrototypeOf(proto);
                }
                console.groupEnd();
            }
        } catch (e) {
            console.warn(`${prefix} 打印属性时出错:`, e);
        }
        console.groupEnd();
    }

    // 完整的对象分析
    analyzeObject(obj, objName = "对象", category = '', showMethodImplementation = false) {
        if (!this.debugMode || !obj) return;
        
        const prefix = this.formatPrefix(category);
        console.group(`${prefix} 分析${objName}`);
        
        try {
            // 基本信息
            console.log(`对象类型: ${obj.constructor ? obj.constructor.name : typeof obj}`);
            
            // 属性和方法
            this.printProperties(obj, objName, category);
            this.printMethods(obj, objName, category, showMethodImplementation);
            
            // 额外信息
            if (obj instanceof Element) {
                console.group('DOM 元素信息:');
                console.log('tagName:', obj.tagName);
                console.log('id:', obj.id);
                console.log('className:', obj.className);
                console.groupEnd();
            }
        } catch (e) {
            console.error(`${prefix} 分析对象时出错:`, e);
        }
        console.groupEnd();
    }

    // 错误日志
    error(message, category = '') {
        console.error(`${this.formatPrefix(category)} 错误:`, message);
    }

    // 警告日志
    warn(message, category = '') {
        console.warn(`${this.formatPrefix(category)} 警告:`, message);
    }

    // 信息日志
    info(message, category = '') {
        console.info(`${this.formatPrefix(category)} 信息:`, message);
    }

    // 调试日志
    debug(message, category = '') {
        if (!this.debugMode) return;
        console.debug(`${this.formatPrefix(category)} 调试:`, message);
    }

    // 分组日志
    group(name, category = '') {
        if (!this.debugMode) return;
        console.group(`${this.formatPrefix(category)} ${name}`);
    }

    groupEnd() {
        if (!this.debugMode) return;
        console.groupEnd();
    }

    // 计时器
    time(label, category = '') {
        if (!this.debugMode) return;
        console.time(`${this.formatPrefix(category)} ${label}`);
    }

    timeEnd(label, category = '') {
        if (!this.debugMode) return;
        console.timeEnd(`${this.formatPrefix(category)} ${label}`);
    }
}

// 创建默认实例
const logger = new Logger('ComfyUI');

// 导出
export { Logger, logger };